﻿using System.Text.RegularExpressions;

namespace Devonline.Core;

/// <summary>
/// 身份证 GB11643-1999
/// </summary>
public class IdentityCard(string idCode)
{
    /// <summary>
    /// 身份证号
    /// </summary>
    private readonly string _idCode = idCode;
    /// <summary>
    /// 省份地区码
    /// </summary>
    private static readonly string[] _address = ["11", "22", "35", "44", "53", "12", "23", "36", "45", "54", "13", "31", "37", "46", "61", "14", "32", "41", "50", "62", "15", "33", "42", "51", "63", "21", "34", "43", "52", "64", "65", "71", "81", "82", "91"];
    /// <summary>
    /// 身份证相对应顺序的加权因子 
    /// </summary>
    private static readonly int[] _weightedFactors = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
    /// <summary>
    /// // 身份证校验数组
    /// </summary>
    private static readonly string _codeVarify = "10X98765432";

    /// <summary>
    /// 18位身份证号码验证
    /// </summary>
    public bool Validate()
    {
        var pattern = @"^\d{17}(?:\d|X)$";
        if (!Regex.IsMatch(_idCode, pattern))
        {
            //格式检查
            return false;
        }

        if (!_address.Contains(_idCode[..AppSettings.UNIT_TWO]))
        {
            //省份验证
            return false;
        }

        if (!_idCode.GetBirthdayFromIdCode().HasValue)
        {
            //出生日期验证
            return false;
        }

        int sum = 0;
        for (int i = 0; i < _idCode.Length - 1; i++)
        {
            sum += _weightedFactors[i] * int.Parse(_idCode[i].ToString());
        }

        //实际校验位的值
        var index = sum % 11;
        if (_codeVarify[index] != char.ToUpperInvariant(_idCode[17]))
        {
            //校验码验证
            return false;
        }

        //符合GB11643-1999标准
        return true;
    }
}